package com.jielin.handling.Annotation;

import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Component;

import com.jielin.handling.entity.accesspath.AccessPath;
import com.jielin.handling.mapper.accesspath.AccessPathMapper;
import com.jielin.handling.util.StringUtil;

/**
 * 解析注解：
 */
@Component
public class SpringUtil implements ApplicationContextAware {

//    @Autowired
//    private AccessPathMapper accessPathMapper;

    private static ApplicationContext applicationContext;
    
  //获取applicationContext
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
        System.out.println("---------------------------------------------------------------------");

        System.out.println("---------------------------------------------------------------------");

        System.out.println("---------------me.shijunjie.util.SpringUtil------------------------------------------------------");

        System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");

        System.out.println("---------------------------------------------------------------------");
	}
    
	
    public void test() throws Exception {

/*        LinkController linkController = new LinkController();
        //获取LinkController的Class实例
        Class<LinkController> c = LinkController.class;
        //获取需要处理的方法Method实例
        Method method = c.getMethod("querylink");
        //判断该方法是否包含Power注解
        if(method.isAnnotationPresent(Power.class)){
            //获取该方法的Power注解实例
            Power power = method.getAnnotation(Power.class);
            //执行该方法
            method.invoke(linkController, new Object[]{});
            //获取Power
            String value1 = power.name();
            System.out.println(value1);
        }
        //获取方法上的所有注解
        Annotation[] annotations = method.getAnnotations();
        for(Annotation annotation : annotations){
            System.out.println(annotation);
        }*/


        AccessPathMapper accessPathMapper = applicationContext.getBean(AccessPathMapper.class);

        // springutil中的资源解析器
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        // 资源解析器路径
        String path = "/com/jielin/handling/controller/**/**.class";
        //获取资源
        Resource[] resources = resolver.getResources(path);

        // 源数据读取工厂
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();


        AccessPath parentpower = null;
        AccessPath childpower = null;

        for (Resource resource : resources) {
            // 读取源数据
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            // 获取class文件的注解数据
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            

            
            // 获取class上的注解
            Map<String, Object> annotationAttributes = annotationMetadata.getAnnotationAttributes(MyPower.class.getName());

            if(annotationAttributes == null) {
            	continue;
            }
            // 获取方法上的注解
            Set<MethodMetadata> annotatedMethods = annotationMetadata.getAnnotatedMethods(MyPower.class.getName());

            //System.out.println("!!!!!" + annotationAttributes);

            if (annotationAttributes.size() > 0) {
                parentpower = new AccessPath();
                parentpower.setContent(annotationAttributes.get("name").toString());
//                parentpower.setMethod(annotationAttributes.get("url").toString());
//                parentpower.setMethod("/");
                parentpower.setMethod("");
                parentpower.setParentId("");
                parentpower.setId(StringUtil.generatorUUID());
                accessPathMapper.addAccessPath(parentpower);

                //System.out.println("#####" + parentpower.getId());
                if (annotatedMethods.size() > 0) {
                    for (MethodMetadata annotatedMethod : annotatedMethods) {
                        childpower = new AccessPath();
                        childpower.setId(StringUtil.generatorUUID());
                        childpower.setContent(annotatedMethod.getAnnotationAttributes(MyPower.class.getName()).get("name").toString());
                        childpower.setMethod(annotationAttributes.get("url").toString()+annotatedMethod.getAnnotationAttributes(MyPower.class.getName()).get("url").toString());
                        childpower.setParentId(parentpower.getId());
                        accessPathMapper.addAccessPath(childpower);

                        //System.out.println(annotatedMethod.getAnnotationAttributes(MyPower.class.getName()));
                    }
                }

            }


        }

    }
    
  //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }


}



